﻿using System;
using System.Collections.Generic;
using System.Linq;
using Atmk.WaterMeter.MIS.Commons;
using Atmk.WaterMeter.MIS.Commons.Interfaces;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Logic;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Repository;
using Atmk.WaterMeter.MIS.Commons.Utils;
using Atmk.WaterMeter.MIS.Commons.ViewModels.District;
using Atmk.WaterMeter.MIS.Datas;
using Atmk.WaterMeter.MIS.Entities;
using Atmk.WaterMeter.MIS.Entities.Enums;
using Atmk.WaterMeter.MIS.Entities.Models;


namespace Atmk.WaterMeter.MIS.Logic
{
    /// <summary>
    /// 片区逻辑层
    /// </summary>
    public class DistrictLogic : IDistrictLogic
    {
        private static readonly NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();

        private readonly IRepository _repository;
        private readonly IDistrictRepository _districtRepository;
        private readonly IStaffRepository _staffRepository;

        public DistrictLogic(
            IRepository repository,
            IDistrictRepository districtRepository,
            IStaffRepository staffRepository
        )
        {
            _repository = repository;
            _districtRepository = districtRepository;
            _staffRepository = staffRepository;
        }


        /// <summary>
        /// 获取Id对应片区下的所有片区信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="arrayDistrictEntities"></param>
        /// <returns></returns>
        public List<District> DistrictEntitiesById(string id, List<District> arrayDistrictEntities)
        {
            //获取区域信息
            List<District> districtList;
            if (arrayDistrictEntities.Count(d => d.Id.ToString() == id) == 0)
            {
                _logger.Warn("id错误，未查到任何数据");
                return new List<District>();
            }

            //获取id下的所有子片区数据
            if (string.IsNullOrEmpty(id))
            {
                //id为空值，默认获取所有
                districtList = arrayDistrictEntities.Where(s => string.IsNullOrEmpty(s.Parent)).ToList();
            }
            else
            {
                districtList = arrayDistrictEntities.Where(s => s.Parent
                                                                == arrayDistrictEntities
                                                                    .First(d => d.Id.ToString() == id).Id.ToString())
                    .ToList();
            }

            return districtList;
        }

        /// <summary>
        /// 获取指定用户ID和区域集合里的主区域信息
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="districts"></param>
        /// <returns></returns>
        public List<District> GetDistrictsMainByUid(string uid, List<District> districts)
        {
            List<District> parentDistricts;

            //根据ID获取操作员信息_repository
            var users = _staffRepository.FindAll<User>().Where(s => s.Id.ToString() == uid).ToList();
            if (users.Count == 0)
            {
                _logger.Warn("操作员编码错误，未查到任何操作员信息");
                return new List<District>();
            }

            var user = users.First();
            if (user.Name == "admin")
            {
                //获取所有父区域集合
                parentDistricts = districts.Where(d => string.IsNullOrEmpty(d.Parent)).ToList();
            }
            else
            {
                //获取片区集合
                var districtids = users.First().DistrictId.Split(',');
                //获取用户下父区域集合
                parentDistricts = districts
                    .Where(d => districtids.Contains(d.Id.ToString()) && string.IsNullOrEmpty(d.Parent))
                    .ToList();
            }

            return parentDistricts;
        }

        /// <summary>
        /// 获得用户ID下所有片区信息
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="districts"></param>
        /// <returns></returns>
        public List<District> GetDistrictsByUid(string uid, List<District> districts)
        {
            var parentDistricts = GetDistrictsMainByUid(uid, districts);
            var result = new List<District>();
            foreach (var t in parentDistricts)
            {
                result.Add(t);
                result.AddRange(
                    districts.Where(d => d.Parent == t.Id.ToString()).ToArray()
                );
            }

            return result;
        }

        /// <summary>
        /// 获取所有区域信息
        /// </summary>
        /// <returns></returns>
        public object SelectDistrict(string uid = "")
        {
            //var districts = Enumerable.ToList<DistrictEntity>(_repository.FindAll<DistrictEntity>());
            //var parentDistricts = GetDistrictsMainByUid(uid, districts);
            ////获取父区域集合
            //var result = new object[parentDistricts.Count];
            //for (var i = 0; i < parentDistricts.Count; i++)
            //{
            //    result[i] = new
            //    {
            //        parentDistrictId = parentDistricts[i].Id,
            //        parentDistrictName = parentDistricts[i].Name,
            //        district = districts.Where(d => d.Parent == parentDistricts[i].Id.ToString()).ToList()
            //            .Select(s => new
            //            {
            //                districtId = s.Id,
            //                districtName = s.Name
            //            })
            //    };
            //}
            //获取所有叶子片区信息
            var districtlist = string.IsNullOrEmpty(uid)
                ? _districtRepository.GetLeafDistrictEntities()
                : _districtRepository.GetLeafDistrictEntities(uid).ToList();
            //获取父区域集合
            var result = new List<object>();
            for (var i = 0; i < districtlist.Count; i++)
            {
                result.Add(new
                {
                    parentDistrictId = districtlist[i].Id,
                    parentDistrictName = districtlist[i].Name,
                    district = districtlist.Where(d => d.Parent == districtlist[i].Id.ToString()).ToList()
                        .Select(s => new
                        {
                            districtId = s.Id,
                            districtName = s.Name
                        })
                });
            }
            return result;
        }

        /// <summary>
        /// 查询指定区域列表数据
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="id">片区id</param>
        /// <param name="page"></param>
        /// <param name="pageSize"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public object SelectDistrict(string uid, string id, int page, int pageSize, out int count)
        {
            List<District> districtList;
            var districts =
                _districtRepository.FindAllAsNoTracking<District>()
                    .ToList();
            //获取id下的所有子片区数据
            if (string.IsNullOrEmpty(id))
            {
                districtList = GetDistrictsByUid(uid, districts);
            }
            else
            {
                if (districts.Count(d => d.Id.ToString() == id) == 0)
                    throw new Exception("id错误，未查到任何数据");
                districtList = districts.Where(s => s.Parent ==
                                                    districts.First(d => d.Id.ToString() == id).Id.ToString()).ToList();
            }

            count = districtList.Count;
            //获取分页数据
            var pageList = PaginatedList<District>.Create(districtList, page, pageSize);
            var result = new object[pageList.Count];
            //赋值
            for (var i = 0; i < pageList.Count; i++)
            {
                result[i] = new
                {
                    districtId = pageList[i].Id, //片区ID
                    parentDistrictId = pageList[i].Parent, //父级片区ID
                    districtName = pageList[i].Name, //片区名称
                    remark = pageList[i].Memo //备注
                };
            }

            return result;
        }

        /// <summary>
        /// 添加片区信息
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="staffId"></param>
        /// <param name="districtId"></param>
        /// <returns></returns>
        public bool InsertDistrict(DistrictInfomationBody obj, string staffId, out string districtId)
        {
            if (!Enum.TryParse<TreeNodeType>(obj.nodeType, out var nodeType))
            {
                nodeType = TreeNodeType.branch; //片区节点类型属性默认branch
            }
            var district = new District()
            {
                ProjectId = obj.projectId,
                Parent = obj.parentDistrictId,
                Name = obj.districtName,
                NodeType = (int)nodeType,
                Memo = obj.remark
            };
            districtId = district.Id;

            using (var _context= ContextBuilder.Build())
            {
                _context.Add(district);
                if (_context.SaveChanges()<=0)
                {
                    return false;
                }
                //var parentId = obj.parentDistrictId != "" ? new Guid(obj.parentDistrictId) : new Guid(obj.projectId);
                //// 添加片区排序
                //DistrictNodeSequences(staffId, districtId, parentId);
                return true;
            }
        }

        /// <summary>
        /// 添加片区排序
        /// </summary>
        /// <param name="staffId"></param>
        /// <param name="ParentId"></param>
        /// <param name="districtId"></param>
        private void DistrictNodeSequences(string staffId, string districtId, Guid ParentId)
        {
            //获取同级片区的排序信息
            var sequences = _districtRepository.GetSameParentDistrictSequence(staffId, ParentId)
                .OrderByDescending(d => d.DisplaySequence).ToList();
            //判断districtId是否存在
            if (sequences.Any(s => s.DistrictId == districtId)) return;
            var index = 0;
            if (sequences.Any())
            {
                index = sequences.First().DisplaySequence + 1;
            }
            var sequence = new DistrictSequences
            {
                DistrictId = districtId,
                StaffId = staffId,
                DisplaySequence = index
            };
            _districtRepository.AddDistrictSequence(sequence);
        }

        /// <summary>
        /// 修改片区信息
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="exception"></param>
        /// <returns></returns>
        public bool UpadateDistrict(dynamic obj, out Exception exception)
        {

            using (var _context = ContextBuilder.Build())
            {
                exception = null;
                var gid = obj.districtId.ToString();
                var district = _context.District.Find(gid);
                district.Name = obj.districtName.ToString();
                district.Memo = obj.remark.ToString();
                _context.Update(district);
                return _context.SaveChanges() > 0;
            }
        }

        /// <summary>
        /// 删除片区信息
        /// </summary>
        /// <param name="id"></param>
        /// <param name="exception"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        public bool DeleteDistrict(string id, string uid, out Exception exception)
        {
            try
            {
                exception = null;
                var listObject = Enumerable.ToList<District>(_repository.FindAll<District>());
                if (listObject.Count(r => r.Id.ToString() == id) == 0)
                {
                    exception = new Exception("没有片区信息");
                    return false;
                }

                if (listObject.Any(
                    t => t.Parent == listObject.First(d => d.Id.ToString() == id).Id.ToString()))
                {
                    exception = new Exception("该片区信息包含其他片区，删除无效");
                    return false;
                }

                var district = listObject.First(r => r.Id.ToString() == id);
                if (_repository.FindAll<Owner>().Any(s =>
                    district.Id.ToString() == s.DistrictId && s.RecordState == (int)RecordStateEnum.Normal))
                {
                    exception = new Exception("删除失败,该片区内有业主信息");
                    return false;
                }


                //片区所属用户不少于1个
                //var staffs = _staffRepository.SelectUserByDistrict(district.Id.ToString());
                //if (staffs.Count > 0)
                //{
                //    exception = new Exception("删除失败,该片区内有业主信息");
                //    return false;
                //}

                if (_repository.Remove(district) > 0)
                {
                    return true;
                }


                exception = new Exception("删除失败");
                return false;
            }
            catch (Exception e)
            {
                exception = e;
                return false;
            }
        }
        public List<District> GetDistrictsLv2(string projectId)
        {
            using (var _context = ContextBuilder.Build())
            {
                var districts = _context.District.Where(m=>m.ProjectId==projectId&&m.NodeType==2).ToList();
                return districts;
            }
        }
        /// <inheritdoc />
        public List<District> GetDistricts(Guid projectId)
        {
            return _districtRepository.GetDistrictEntities(projectId.ToId()).OrderBy(d => d.CreateTime).ToList();
        }

        /// <inheritdoc />
        public List<DistrictSequences> GetDistrictOrder(string staffId)
        {
            return _districtRepository.GetDistrictSequencebyStaff(staffId);
        }

        /// <inheritdoc />
        public District GetDistrict(Guid districtGuid)
        {
            return _districtRepository.GetDistrictsById(districtGuid.ToId()).First();
        }

        /// <inheritdoc />
        public bool UpdateSequences(DistrictNodeSequence[] sequences)
        {
            throw new NotImplementedException();
        }


    }
}